open Printf
open Jopruntime
open Jopruntime.Circuit

let half_add a b =
  < s,c >
    | s = xor_ a b
    | c = and_ a b
;;

let half_add_bug bug a b =
  < s,c >
    | s = xor_ a b
    | (if bug then 
	  | c = xor_ a b
      else
	  | c = and_ a b
    )
;;

let full_add a b ci =
  < s,co ; u,v,w >
    | u,v = half_add a b
    | s,w = half_add u ci
    | co = or_ w v
;;

let rec counter n i =
  let count1 a =
    < s,c ; u >
    | u = xor_ a s
    | s = reg u
    | c = and_ a s
  in
  if n = 1 then count1 i
  else (
    < s[0 .. n-1], c_out; c_in >
	   | s[1 .. n-1], c_in = counter (n-1) i
	   | s[0], c_out = count1 c_in
  )
;;

(*let main () =
  < ; a,b,ci,s,co >
    | a = input "A" 1
    | b = input "B" 1
    | ci = input "Ci" 1
    | s,co = full_add a b ci
    | (output "S" co@s)
;;*)

let main3 () =
  let size = 3 in
  <  ; i, s[0 .. size-1], c >
    | i = input "I" 1
    | s, c = counter size i
    | (output "S" s)
    | (output "C" c)
;;

(*let main2 () =
  < ; a, b, c >
    | c = xor_ a b
	| (output "Coucou" [c])
;;*)
Printf.printf "Size: %d\n" (List.length (snd (counter 2 [0])));;
let c = NetList.generate (fst (main3 ()));;
temp_gen c Sys.argv.(1);;
